﻿layui.define(['context', 'popup'], function (exports) {
    "use strict";

    var $ = layui.jquery;
    var layer = layui.layer;
    var context = layui.context;
    var popup = layui.popup;

    var http = {};
    var loadIndex = 0
    http.ajax = function (userOptions) {
        userOptions = userOptions || {};

        var options = $.extend(true, {}, http.ajax.defaultOpts, userOptions);
        var oldBeforeSendOption = options.beforeSend;
        options.beforeSend = function (xhr) {
            if (oldBeforeSendOption) {
                oldBeforeSendOption(xhr);
            }

            //loading
            if (options.loading) loadIndex = layer.msg('加载中', { icon: 16, shade: 0.2 });

            xhr.setRequestHeader("Pragma", "no-cache");
            xhr.setRequestHeader("Cache-Control", "no-cache");
            xhr.setRequestHeader("Expires", "Sat, 01 Jan 2020 00:00:00 GMT");
        };

        options.success = undefined;
        options.error = undefined;

        return $.Deferred(function ($dfd) {
            $.ajax(options)
                .done(function (data, textStatus, jqXHR) {
                    if (options.loading) layer.close(loadIndex);
                    //登录过期，返回登录界面
                    if (data.code == 401) {
                        popup.failure(data.message, function () {
                            window.location.href = "/";
                        })
                        return;
                    }
                    $dfd.resolve(data);
                    userOptions.success && userOptions.success(data);
                })
                .fail(function (jqXHR) {
                    if (options.loading) layer.close(loadIndex);
                    http.ajax.handleErrorResponse(jqXHR, userOptions, $dfd);
                });
        });
    }

    // get请求
    http.get = (url, data = {}, loading = true) => {
        return http.ajax({
            type: 'GET',
            url,
            data,
            loading
        });
    }

    // post请求
    http.post = (url, data = {}, loading = true) => {
        return http.ajax({
            url,
            type: 'POST',
            data: JSON.stringify(data),
            loading            
        });
    }

    // put请求
    http.put = (url, data = {}, header = {}) => {
        return http.ajax({
            url,
            type: 'PUT',
            header,
            data
        });
    }

    // delete请求
    http.delete = (url, data = {}, header = {}) => {
        return http.ajax({
            url,
            type: 'DELETE',
            header,
            data
        });
    }
    // 设置\获取token
    http.setAuthorizationToken = function (token) {
        return context.put(http.ajax.authorizationTokenName, 'Bearer ' + token);
    }
    http.getToken = function () {
        return context.get(http.ajax.authorizationTokenName);
    }

    $.extend(http.ajax, {
        defaultOpts: {
            loading: true,
            dataType: 'json',
            type: 'POST',
            contentType: 'application/json',
            headers: {
                'X-Requested-With': 'XMLHttpRequest'
            }
        },

        defaultError: {
            message: 'An error has occurred!',
            details: 'Error detail not sent by server.'
        },

        defaultError401: {
            message: 'You are not authenticated!',
            details: 'You should be authenticated (sign in) in order to perform this operation.'
        },

        defaultError403: {
            message: 'You are not authorized!',
            details: 'You are not allowed to perform this operation.'
        },

        defaultError404: {
            message: 'Resource not found!',
            details: 'The resource requested could not found on the server.'
        },

        logError: function (error) {
            console.log(error);
        },

        showError: function (error) {
            if (error.details) {
                return layer.alert(error.details, {
                    title: error.message,
                    icon: 2,
                    closeBtn: 0
                });
            } else {
                return layer.alert(http.ajax.defaultError.details, {
                    title: error.message || http.ajax.defaultError.message,
                    icon: 2,
                    closeBtn: 0
                });
            }
        },

        showErrorAndRedirectUrl: function (error, targetUrl) {
            if (error.details) {
                return layer.alert(error.details, {
                    title: error.message,
                    icon: 2,
                    closeBtn: 0,
                    end: http.ajax.handleTargetUrl(targetUrl)
                });
            } else {
                return layer.alert(http.ajax.defaultError.details, {
                    title: error.message || http.ajax.defaultError.message,
                    icon: 2,
                    closeBtn: 0,
                    end: http.ajax.handleTargetUrl(targetUrl)
                });
            }
        },

        handleTargetUrl: function (targetUrl) {
            if (!targetUrl) {
                location.href = http.appPath;
            } else {
                location.href = targetUrl;
            }
        },

        handleErrorResponse: function (jqXHR, userOptions, $dfd) {
            if (userOptions.customHandleError !== false) {
                switch (jqXHR.status) {
                    case 401:
                        http.ajax.showErrorAndRedirectUrl(http.ajax.defaultError401, '/User/Login');
                        break;
                    case 403:
                        http.ajax.showError(http.ajax.defaultError403);
                        break;
                    case 404:
                        http.ajax.showError(http.ajax.defaultError404);
                        break;
                    default:
                        http.ajax.showError(http.ajax.defaultError);
                        break;
                }
            }

            $dfd.reject.apply(this, arguments);
            userOptions.error && userOptions.error.apply(this, arguments);
        },

        ajaxSendHandler: function (event, request, settings) {
            if (!settings.headers || settings.headers[http.ajax.tokenHeaderName] === undefined) {
                var token = http.ajax.getToken();
                if (token) {
                    request.setRequestHeader(http.ajax.tokenHeaderName, token);
                }
            }

            if (!settings.headers || settings.headers[http.ajax.authorizationHeaderName] === undefined) {
                var token = http.ajax.getAuthorizationToken();
                if (token) {
                    request.setRequestHeader(http.ajax.authorizationHeaderName, token);
                }
            }
        },

        getToken: function () {
            return http.ajax.getCookieValue(http.ajax.tokenCookieName);
        },
        getAuthorizationToken: function () {
            return context.get(http.ajax.authorizationTokenName);
        },

        tokenCookieName: 'XSRF-TOKEN',
        tokenHeaderName: 'X-XSRF-TOKEN',
        authorizationHeaderName: 'Authorization',
        authorizationTokenName: 'token',

        getCookieValue: function (key) {
            var equalities = document.cookie.split('; ');
            for (var i = 0; i < equalities.length; i++) {
                if (!equalities[i]) {
                    continue;
                }

                var splitted = equalities[i].split('=');
                if (splitted.length != 2) {
                    continue;
                }

                if (decodeURIComponent(splitted[0]) === key) {
                    return decodeURIComponent(splitted[1] || '');
                }
            }

            return null;
        }
    });



    $(document).ajaxSend(function (event, request, settings) {
        return http.ajax.ajaxSendHandler(event, request, settings);
    });

    exports('http', http);
});